#include "LPC11xx.h"
#include "delay.h"
#include "uart.h"
#include <stdio.h>

//向串口发送一个字节
void uart_send_byte(int c)
{
  //等待发送保持寄存器为空
  while(!(LPC_UART->LSR & (1 << 5)));
  LPC_UART->THR = c;
}

//从串口读取一个字节
//返回读取的字符，超时返回EOF
int uart_recv_byte(uint32_t timeout)
{
  uint8_t byte = 0;
  uint32_t begin = tick_count;
  //接收队列为空执行循环等待
  while (!(LPC_UART->LSR & 1))
  {
    //超时
    if (tick_count - begin >= timeout)
    {
      return EOF;
    }
  }
  
  //从接收队列中读取数据
  byte = LPC_UART->RBR;
  
  return byte;
}

//将标准IO输出重定向到串口
int fputc(int c, FILE* fp)
{
  uart_send_byte(c);
  return c;
}

int fgetc(FILE* fp)
{
  return uart_recv_byte(100);
}

void uart_init(int baudrate)
{
  uint32_t div = 0;
  //1. 启用IOCONFIG模块
  LPC_SYSCON->SYSAHBCLKCTRL |= 1 << 16;
  
  //2. 配置引脚功能
  //将PIO1_6引脚设置为串口RX引脚
  LPC_IOCON->PIO1_6 |= 1;
  //将PIO1_7引脚设置为串口TX引脚
  LPC_IOCON->PIO1_7 |= 1;
  
  //3. 启用串口时钟
  LPC_SYSCON->SYSAHBCLKCTRL |= 1 << 12;
  
  //4. 设置串口外设时钟频率（不分频）
  LPC_SYSCON->UARTCLKDIV = 1;
  
  //5. 设置数据位，停止位和奇偶校验
  //设置数据位个数为8bit
  LPC_UART->LCR |= 3;
  
  //6. 设置波特率
  div = SystemCoreClock/LPC_SYSCON->UARTCLKDIV/baudrate/16;
  
  //开始配置波特率
  LPC_UART->LCR |= 1 << 7;
  
  LPC_UART->DLL = div & 0xff;
  LPC_UART->DLM = div >> 8;
  
  //波特率配置结束
  LPC_UART->LCR &= ~(1 << 7);
  
  //7. 启用并清空FIFO
  LPC_UART->FCR = 7;
}
